package entity

import (
	"Agenda/deepCopyInterface"
	"encoding/json"
	"fmt"
	"io"
	"os"
)

var temp_username string
var userList []User

var userDataPath = "src/user.txt"
var tempuserPath = "src/temp_user.txt"

func init() {
	LoadUserData(userDataPath)
	loadTempUsername()
}

func loadTempUsername() {
	readTemUser()
}

func LoadUserData(Path string) error {
	if err := readStr(Path); err != nil {
		fmt.Println("load user data failed")
	}
	return nil
}

func Logout() (bool, error) {
	err := setTempUser("")
	if err != nil {
		return false, err
	}
	return true, nil
}

func checkIfExistName(name string) bool {
	for _, value := range userList {
		if value.Name == name {
			return true
		}
	}
	return false
}

func Login(name, password string) (bool, error) {
	if temp_username != "" {
		fmt.Println("please logout first")
		return false, nil
	}
	if sameFlag := checkIfExistName(name); sameFlag == false {
		return false, nil
	}
	if flag, err := comparePassword(name, password); err != nil || flag == false {
		return false, err
	}
	if err := setTempUser(name); err != nil {
		return false, err
	}
	temp_username = name
	fmt.Println(temp_username, " login succeed!")
	return true, nil
}

func setTempUser(name string) error {
	if err := writeJSON(tempuserPath, name); err != nil {
		fmt.Println("write error")
		return err
	}
	return nil
}

func comparePassword(name, password string) (bool, error) {
	for _, value := range userList {
		if value.Name == name && value.Password == password {
			return true, nil
		}
	}
	return false, nil
}

func CreateUser(name, password, email, phone string) (bool, error) {
	if sameFlag := checkIfExistName(name); sameFlag == true {
		return sameFlag, nil
	}

	temp_user := User{
		name,
		password,
		email,
		phone,
	}
	userList = append(userList, deepCopyInterface.Copy(temp_user).(User))
	if err := sync(); err != nil {
		return false, err
	}
	return false, nil
}

func readTemUser() error {
	file, err := os.Open(tempuserPath)
	if err != nil {
		fmt.Println("open file error")
	}
	defer file.Close()

	dec := json.NewDecoder(file)
	switch err := dec.Decode(&temp_username); err {
	case nil, io.EOF:
		return nil
	default:
		fmt.Println("Decode User Fail because : ", err)
		return err
	}
}

func readStr(Path string) error {
	file, err := os.Open(Path)
	if err != nil {
		fmt.Println("open file error")
	}
	defer file.Close()

	dec := json.NewDecoder(file)
	switch err := dec.Decode(&userList); err {
	case nil, io.EOF:
		return nil
	default:
		fmt.Println("Decode User Fail because : ", err)
		return err
	}
}

func sync() error {
	if err := writeToFile(userDataPath); err != nil {
		fmt.Println("sync error")
		return err
	}
	return nil
}

func writeToFile(Path string) error {
	if err := writeJSON(Path, userList); err != nil {
		fmt.Println("write error")
		return err
	}
	return nil
}

func writeJSON(fpath string, data interface{}) error {
	file, err := os.Create(fpath)
	if err != nil {
		return err
	}
	defer file.Close()

	enc := json.NewEncoder(file)

	if err := enc.Encode(&data); err != nil {
		fmt.Println("writeJSON:", err)
		return err
	}
	return nil
}
